<?php

/* * 这是一个计数器* */

class CounterD {

    protected $_levels = array();
    protected $_filters = array();
    protected $_attributes = array();
    public $modelName = '';
    protected $_offset = array();

    /**
      添加统计登记
      $unit 可能的值为0,2,4,8对应：小时，天，月，年，至入库以来
      $levelValue为单位,通常和$unit组合使用  addLevel(2,8) 则表示每8小时的计数统计结果
     * */
    public function __construct() {
        $this->_levels [16] = 1;
        $this->_offset [16] = $_SERVER ['REQUEST_TIME'];
    }

    public function addLevel($unit, $levelValue = 1) {
        if ($unit !== 0 && $unit !== 2 && $unit !== 4 && $unit !== 8 && $unit !== 16) {
            throw new Exception('第一个参数不正确，只能为2的次幂，且小于d等于128');
        }
        switch ($unit) {
            case 0 :
                $this->_offset [0] = $_SERVER ['REQUEST_TIME'] + $levelValue * 3600;
                break;
            case 2 :
                $this->_offset [2] = $_SERVER ['REQUEST_TIME'] + $levelValue * 86400;
                break;
            case 4 :
                $this->_offset [4] = strtotime("+ {$levelValue} months");
                break;
            case 8 :
                $this->_offset [8] == strtotime("+ {$levelValue} years");
                break;
        }
        $this->_levels [$unit] = $levelValue;
        return $this;
    }

    /*     * 增加过滤 第一个参数表示过滤字段，第二个参数为过去条件 array('eq','127.0.0.1'),支持表达式符号 如eq in gt lt等
      如设置根据ip计数，addFilter('ip',artray('eq','127.0.0.1'))
      如果不调用这个方法，则每次请求都将增加1
     * */

    public function addFilter($colum, array $condition) {
        $this->_levels [$colum] [] = $condition;
        return $this;
    }

    public function setAttributes(array $attributes) {
        $this->_attributes = $attributes;
    }

    /*     * 更新统计记录到mongodb* */

    public function recoredHits($modelName) {
        //往缓冲中写入数据
        $modelName = strtolower($modelName);
        $writer = Yii::app()->counterWriter;
        if (!isset($this->_attributes ['content_id'])) {
            throw new Exception('必须设置content_id属性');
        }
        if (!isset($this->_attributes ['title'])) {
            throw new Exception('必须设置title属性');
        }
        foreach ($this->_attributes as $key => $value) {
            $writer->eq($key, $value);
        }
        foreach ($this->_filters as $key => $value) {
            if (is_array($value)) {
                foreach ($value as $v) {
                    $writer->$v [0]($key, $v [1]);
                }
            }
        }
        $this->_attributes ['ip'] = Yii::app()->request->getUserHostAddress();
        $writer->addIndex($modelName, array('content_id' => 1));
        $writer->update($modelName, $this->_attributes, array("upsert" => true));
    }

    /*     * 同步mongodb并将统计次数更新到数据库* */

    public function updateHits(CActiveRecord $model) {
        $modelName = strtolower(get_class($model));
        //获得表名
        switch ($modelName) {
            case 'discounthit':
                $db_table = 'tbl_discount_hit';
                break;
            case 'newshit':
                $db_table = 'tbl_news_hit';
                break;
            case 'shophit':
                $db_table = 'tbl_shop_hit';
                break;
        }
        $reader = Yii::app()->counterReader;
        try {
            $data = $reader->gt('content_id', 0)->group($modelName, array('content_id' => 1)); //获得每小时的数据
        } catch (Exception $ex) {
            exit($ex->getMessage());
        }
        $writer = Yii::app()->counterWriter;
        $writer->gt('content_id', 0)->remove($modelName); //删除数据
        if (!empty($data ['retval']) && is_array($data ['retval'])) {
            foreach ($data ['retval'] as $val) {
                $models = $model->getListByPage(1, 5, array('condition' => 'content_id=' . $val ['content_id']));
                if (count($models ['data'])) {
                    foreach ($models ['data'] as $m) {
                        $attrs = array(
                            'content_id'=> $m ['content_id'],
                            'title'=> $m ['title'],
                            'unit'=> $m ['unit'],
                            'unit_value'=> $m ['unit_value'],
                            'hit_time'=> $m ['hit_time'],
                            'amount'=> $m ['amount'],
                            'area_code'=> $m ['area_code'],
                            'logo'=> $m ['logo']
                        );
                        if ($m ['hit_time'] < $_SERVER ['REQUEST_TIME']) {
                            if ($m ['unit'] != 16) {
                                $attrs['amount']=$val ['count'];
                                $attrs['hit_time']=$this->_offset [$m ['unit']];
                            } else {                                
                                $attrs['amount']+= (int) $val ['count'];
                                $attrs['hit_time']=$this->_offset [$m ['unit']];                             
                            }
                        } else {                        
                                $attrs['amount']+= (int) $val ['count'];
                                if ($m ['unit'] == 16) {
                                 $attrs['hit_time']=$this->_offset [$m ['unit']];    
                                }                  
                        }
                        //修改成原生态的执行语句
                        UtilD::clearNullOrEmptyValue($attrs);
                        Yii::app()->hitDbWriteonly->createCommand()->update($db_table, $attrs, 'id=:id', array(':id' => $m ['id']));
                        /*
                          unset($this->_offset [$m ['unit']]);
                          unset($this->_levels [$m ['unit']]);
                         */                        
                    }

                    /*
                      if (count($this->_offset)) {
                      $model->setIsNewRecord(true);
                      foreach ($this->_levels as $k => $v) {
                      $model->id = null;
                      $model->content_id = $val ['content_id'];
                      $model->title = $val ['title'];
                      $model->amount = $val ['count'];
                      $model->logo = $val['logo'];
                      $model->area_code = $val ['area_code'];
                      $model->hit_time = $this->_offset [$k];
                      $model->unit = $k;
                      $model->unit_value = $v;
                      $model->save();
                      }
                      }
                     * 
                     */
                } else {
                    foreach ($this->_levels as $k => $v) {
                        $model->setIsNewRecord(true);
                        $model->id = null;
                        $model->content_id = $val ['content_id'];
                        $model->logo = $val['logo'];
                        $model->area_code = $val ['area_code'];
                        $model->title = $val ['title'];
                        $model->amount = $val ['count'];
                        $model->hit_time = $this->_offset [$k];
                        $model->unit = $k;
                        $model->unit_value = $v;
                        $model->save();
                    }
                }
            }
        }
    }

}

?>